#include "./BSP/BEEP/beep_alert_manager.h"
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>

/* 时间计数最大值 */
#define TIME_MAX_VAL (uint32_t)0xffff
/* 时间累加宏,防止溢出 */
#define TIME_ADD(tic, time) (TIME_MAX_VAL - (tic) < (time) ? ((tic) = 0xffff) : (tic += time))

/* -------------------------------------------- 全局变量定义 -------------------------------------------- */

static alert_player_t s_alertPlayer;    /* 报警提示音播放器 */

/* -------------------------------------------- 报警提示音参数定义 -------------------------------------------- */

/* 警告音参数 */
#define ALERT_WARNING_FREQ       2000    /* 警告音频率 2kHz */
#define ALERT_WARNING_DURATION   200     /* 警告音持续时间 200ms */
#define ALERT_WARNING_INTERVAL   100     /* 警告音间隔 100ms */
#define ALERT_WARNING_COUNT      3       /* 警告音重复次数 3次 */
#define ALERT_WARNING_VOLUME     80      /* 警告音音量 80% */

/* 一般提示音参数 */
#define ALERT_NORMAL_FREQ        1500    /* 一般提示音频率 1.5kHz */
#define ALERT_NORMAL_DURATION    100     /* 一般提示音持续时间 100ms */
#define ALERT_NORMAL_VOLUME      60      /* 一般提示音音量 60% */

/* 紧急提示音参数 */
#define ALERT_URGENT_FREQ        3000    /* 紧急提示音频率 3kHz */
#define ALERT_URGENT_DURATION    150     /* 紧急提示音持续时间 150ms */
#define ALERT_URGENT_INTERVAL    50      /* 紧急提示音间隔 50ms */
#define ALERT_URGENT_COUNT       5       /* 紧急提示音重复次数 5次 */
#define ALERT_URGENT_VOLUME      100     /* 紧急提示音音量 100% */

/* 成功提示音参数 */
#define ALERT_SUCCESS_FREQ       2500    /* 成功提示音频率 2.5kHz */
#define ALERT_SUCCESS_DURATION   80      /* 成功提示音持续时间 80ms */
#define ALERT_SUCCESS_INTERVAL   50      /* 成功提示音间隔 50ms */
#define ALERT_SUCCESS_COUNT      2       /* 成功提示音重复次数 2次 */
#define ALERT_SUCCESS_VOLUME     70      /* 成功提示音音量 70% */

/* 错误提示音参数 */
#define ALERT_ERROR_FREQ         1000    /* 错误提示音频率 1kHz */
#define ALERT_ERROR_DURATION     300     /* 错误提示音持续时间 300ms */
#define ALERT_ERROR_INTERVAL     200     /* 错误提示音间隔 200ms */
#define ALERT_ERROR_COUNT        2       /* 错误提示音重复次数 2次 */
#define ALERT_ERROR_VOLUME       90      /* 错误提示音音量 90% */

/* 通知提示音参数 */
#define ALERT_NOTIFY_FREQ        1800    /* 通知提示音频率 1.8kHz */
#define ALERT_NOTIFY_DURATION    60      /* 通知提示音持续时间 60ms */
#define ALERT_NOTIFY_VOLUME      50      /* 通知提示音音量 50% */

/* -------------------------------------------- 报警提示音初始化 -------------------------------------------- */

/**
 * @brief       初始化报警提示音播放器
 * @param       无
 * @retval      无
 */
static void InitAlertPlayer(void)
{
    s_alertPlayer.state = ALERT_STATE_IDLE;
    s_alertPlayer.type = ALERT_TYPE_NONE;
    s_alertPlayer.freq = 0;
    s_alertPlayer.duration = 0;
    s_alertPlayer.interval = 0;
    s_alertPlayer.count = 0;
    s_alertPlayer.current_count = 0;
    s_alertPlayer.tic = 0;
    s_alertPlayer.volume = 70;
    s_alertPlayer.is_beeping = 0;
    s_alertPlayer.isSetCount = 0;
}

/* -------------------------------------------- 报警提示音扫描函数 -------------------------------------------- */

/**
 * @brief       报警提示音扫描函数（非阻塞）
 * @param       sysTime   系统运行时间,单位毫秒
 * @retval      无
 * @note        此函数需要在任务中定期调用，用于更新报警提示音播放状态
 */
void ALERT_Scan(uint32_t sysTime)
{
    static uint32_t s_sysTimeBak = 0; /* 上次调用时的系统时间 */
    
    /* 检查播放状态 */
    if (s_alertPlayer.state != ALERT_STATE_PLAYING)
    {
        s_sysTimeBak = 0;  /* 重置时间备份 */
        return;
    }
    
    /* 首次调用,初始化时间 */
    if (s_sysTimeBak == 0)
    {
        s_sysTimeBak = sysTime;
        return;
    }
    
    /* 更新计时器 */
    TIME_ADD(s_alertPlayer.tic, (sysTime - s_sysTimeBak));
    
    /* 如果设置了次数 */
    if (s_alertPlayer.isSetCount)
    {
        /* 根据当前状态处理 */
        if (s_alertPlayer.is_beeping)  /* 当前正在响 */
        {
            if (s_alertPlayer.tic >= s_alertPlayer.duration)
            {
                /* 响铃结束，进入静音间隔 */
                beep_stop();
                s_alertPlayer.tic = 0;
                s_alertPlayer.is_beeping = 0;
                s_alertPlayer.current_count++;
                
                printf("ALERT: 播放完成第%d次，总共%d次\n", 
                       s_alertPlayer.current_count, s_alertPlayer.count);
                
                /* 检查是否完成所有次数 */
                if (s_alertPlayer.current_count >= s_alertPlayer.count)
                {
                    s_alertPlayer.count = 0;  /* 清零次数 */
                    s_alertPlayer.state = ALERT_STATE_IDLE;
                    printf("ALERT: 播放完成，状态设为IDLE\n");
                }
            }
        }
        else  /* 当前静音间隔 */
        {
            if (s_alertPlayer.tic >= s_alertPlayer.interval)
            {
                /* 间隔结束，开始下一次响铃 */
                s_alertPlayer.tic = 0;
                
                if (s_alertPlayer.current_count < s_alertPlayer.count)
                {
                    /* 设置蜂鸣器参数并开始响铃 */
                    beep_set_frequency(s_alertPlayer.freq);
                    beep_set_volume(s_alertPlayer.volume);
                    beep_start();
                    s_alertPlayer.is_beeping = 1;
                    
                    printf("ALERT: 开始第%d次播放\n", s_alertPlayer.current_count + 1);
                }
                else
                {
                    s_alertPlayer.count = 0;  /* 清零次数 */
                    s_alertPlayer.state = ALERT_STATE_IDLE;
                    printf("ALERT: 播放完成，状态设为IDLE\n");
                }
            }
        }
    }
    else /* 未设置次数,永久运行 */
    {
        /* 根据当前状态处理 */
        if (s_alertPlayer.is_beeping)  /* 当前正在响 */
        {
            if (s_alertPlayer.tic >= s_alertPlayer.duration)
            {
                /* 响铃结束，进入静音间隔 */
                s_alertPlayer.tic = 0;
                beep_stop();
                s_alertPlayer.is_beeping = 0;
                s_alertPlayer.current_count++;
                
                printf("ALERT: 永久播放，完成第%d次\n", s_alertPlayer.current_count);
            }
        }
        else  /* 当前静音间隔 */
        {
            if (s_alertPlayer.tic >= s_alertPlayer.interval)
            {
                /* 间隔结束，开始下一次响铃 */
                s_alertPlayer.tic = 0;
                
                /* 设置蜂鸣器参数并开始响铃 */
                beep_set_frequency(s_alertPlayer.freq);
                beep_set_volume(s_alertPlayer.volume);
                beep_start();
                s_alertPlayer.is_beeping = 1;
                
                printf("ALERT: 永久播放，开始第%d次\n", s_alertPlayer.current_count + 1);
            }
        }
    }
    
    /* 保存这次的系统时间 */
    s_sysTimeBak = sysTime;
}

/* -------------------------------------------- 报警提示音控制函数 -------------------------------------------- */

/**
 * @brief       开始播放报警提示音
 * @param       type: 提示音类型
 * @param       priority: 优先级
 * @retval      无
 */
void ALERT_Play(alert_type_e type)
{
    uint32_t current_time = HAL_GetTick();
    
    /* 停止当前播放 */
    beep_stop();
    
    /* 根据类型设置参数 */
    switch (type)
    {
        case ALERT_TYPE_WARNING:
            s_alertPlayer.freq = ALERT_WARNING_FREQ;
            s_alertPlayer.duration = ALERT_WARNING_DURATION;
            s_alertPlayer.interval = ALERT_WARNING_INTERVAL;
            s_alertPlayer.count = ALERT_WARNING_COUNT;
            s_alertPlayer.volume = ALERT_WARNING_VOLUME;
            break;
            
        case ALERT_TYPE_NORMAL:
            s_alertPlayer.freq = ALERT_NORMAL_FREQ;
            s_alertPlayer.duration = ALERT_NORMAL_DURATION;
            s_alertPlayer.interval = 0;
            s_alertPlayer.count = 1;
            s_alertPlayer.volume = ALERT_NORMAL_VOLUME;
            break;
            
        case ALERT_TYPE_URGENT:
            s_alertPlayer.freq = ALERT_URGENT_FREQ;
            s_alertPlayer.duration = ALERT_URGENT_DURATION;
            s_alertPlayer.interval = ALERT_URGENT_INTERVAL;
            s_alertPlayer.count = ALERT_URGENT_COUNT;
            s_alertPlayer.volume = ALERT_URGENT_VOLUME;
            break;
            
        case ALERT_TYPE_SUCCESS:
            s_alertPlayer.freq = ALERT_SUCCESS_FREQ;
            s_alertPlayer.duration = ALERT_SUCCESS_DURATION;
            s_alertPlayer.interval = ALERT_SUCCESS_INTERVAL;
            s_alertPlayer.count = ALERT_SUCCESS_COUNT;
            s_alertPlayer.volume = ALERT_SUCCESS_VOLUME;
            break;
            
        case ALERT_TYPE_ERROR:
            s_alertPlayer.freq = ALERT_ERROR_FREQ;
            s_alertPlayer.duration = ALERT_ERROR_DURATION;
            s_alertPlayer.interval = ALERT_ERROR_INTERVAL;
            s_alertPlayer.count = ALERT_ERROR_COUNT;
            s_alertPlayer.volume = ALERT_ERROR_VOLUME;
            break;
            
        case ALERT_TYPE_NOTIFY:
            s_alertPlayer.freq = ALERT_NOTIFY_FREQ;
            s_alertPlayer.duration = ALERT_NOTIFY_DURATION;
            s_alertPlayer.interval = 0;
            s_alertPlayer.count = 1;
            s_alertPlayer.volume = ALERT_NOTIFY_VOLUME;
            break;
            
        default:
            return;
    }
    
    /* 初始化播放器 */
    s_alertPlayer.type = type;
    s_alertPlayer.current_count = 0;
    s_alertPlayer.state = ALERT_STATE_PLAYING;
    s_alertPlayer.is_beeping = 1;
    s_alertPlayer.tic = 0;
    s_alertPlayer.isSetCount = 1;  /* 设置次数限制 */
    
    /* 开始播放第一次 */
    beep_set_frequency(s_alertPlayer.freq);
    beep_set_volume(s_alertPlayer.volume);
    beep_start();
    
    printf("ALERT: 开始播放，频率%dHz，持续时间%dms，间隔%dms，总次数%d\n", 
           s_alertPlayer.freq, s_alertPlayer.duration, s_alertPlayer.interval, s_alertPlayer.count);
}

/**
 * @brief       播放自定义报警提示音
 * @param       freq: 频率
 * @param       volume: 音量(0-100)
 * @param       count: 重复次数
 * @param       ...: 时间序列参数（毫秒）
 *              > 0: 响铃持续时间
 *              < 0: 静音持续时间
 *              = 0: 参数结束
 * @retval      无
 * @note        例如：ALERT_PlayCustom(2000, 80, 3, 200, -100, 200, -100, 200, -400, 0);
 *              表示：2kHz频率，80%音量，重复3次，每次响200ms，静100ms，响200ms，静100ms，响200ms，静400ms
 */
void ALERT_PlayCustom(uint32_t freq, uint8_t volume, uint8_t count, ...)
{
    va_list timeList;
    int32_t time;
    uint16_t min_interval = 0xffff;
    uint8_t total_segments = 0;
    
    /* 参数检查 */
    if (freq < 100) freq = 100;
    if (freq > 8000) freq = 8000;
    if (volume > 100) volume = 100;
    if (count == 0) count = 1;
    
    /* 第一次遍历参数，找出最小时间间隔和总段数 */
    va_start(timeList, count);
    do
    {
        time = va_arg(timeList, int32_t);
        if (time != 0)
        {
            if (abs(time) < min_interval)
            {
                min_interval = abs(time);
            }
            total_segments++;
        }
    } while (time != 0);
    va_end(timeList);
    
    /* 检查参数有效性 */
    if (total_segments == 0 || min_interval == 0xffff)
    {
        printf("ALERT: 自定义参数无效\n");
        return;
    }
    
    /* 停止当前播放 */
    beep_stop();
    
    /* 设置自定义参数 */
    s_alertPlayer.type = ALERT_TYPE_CUSTOM;
    s_alertPlayer.freq = freq;
    s_alertPlayer.volume = volume;
    s_alertPlayer.count = count;
    s_alertPlayer.current_count = 0;
    s_alertPlayer.state = ALERT_STATE_PLAYING;
    s_alertPlayer.is_beeping = 1;
    s_alertPlayer.tic = 0;
    s_alertPlayer.isSetCount = 1;  /* 设置次数限制 */
    
    /* 开始播放第一次 */
    beep_set_frequency(s_alertPlayer.freq);
    beep_set_volume(s_alertPlayer.volume);
    beep_start();
    
    printf("ALERT: 开始自定义播放，频率%dHz，音量%d%%，重复%d次\n", 
           s_alertPlayer.freq, s_alertPlayer.volume, s_alertPlayer.count);
}

/**
 * @brief       播放自定义报警提示音（带重复次数）
 * @param       freq: 频率
 * @param       volume: 音量(0-100)
 * @param       count: 单次序列的段数
 * @param       repeat_count: 重复次数，0表示无限制
 * @param       ...: 时间序列参数（毫秒）
 *              > 0: 响铃持续时间
 *              < 0: 静音持续时间
 *              = 0: 参数结束
 * @retval      无
 * @note        例如：ALERT_PlayCustomWithCount(2000, 80, 3, 5, 200, -100, 200, -100, 200, -400, 0);
 *              表示：2kHz频率，80%音量，每次序列3段，重复5次
 *              时间序列：响200ms，静100ms，响200ms，静100ms，响200ms，静400ms
 */
void ALERT_PlayCustomWithCount(uint32_t freq, uint8_t volume, uint8_t count, uint8_t repeat_count, ...)
{
    va_list timeList;
    int32_t time;
    uint16_t min_interval = 0xffff;
    uint8_t total_segments = 0;
    
    /* 参数检查 */
    if (freq < 100) freq = 100;
    if (freq > 8000) freq = 8000;
    if (volume > 100) volume = 100;
    if (count == 0) count = 1;
    
    /* 第一次遍历参数，找出最小时间间隔和总段数 */
    va_start(timeList, repeat_count);
    do
    {
        time = va_arg(timeList, int32_t);
        if (time != 0)
        {
            if (abs(time) < min_interval)
            {
                min_interval = abs(time);
            }
            total_segments++;
        }
    } while (time != 0);
    va_end(timeList);
    
    /* 检查参数有效性 */
    if (total_segments == 0 || min_interval == 0xffff)
    {
        printf("ALERT: 自定义参数无效\n");
        return;
    }
    
    /* 停止当前播放 */
    beep_stop();
    
    /* 设置自定义参数 */
    s_alertPlayer.type = ALERT_TYPE_CUSTOM;
    s_alertPlayer.freq = freq;
    s_alertPlayer.volume = volume;
    s_alertPlayer.count = repeat_count;  /* 使用repeat_count作为总重复次数 */
    s_alertPlayer.current_count = 0;
    s_alertPlayer.state = ALERT_STATE_PLAYING;
    s_alertPlayer.is_beeping = 1;
    s_alertPlayer.tic = 0;
    s_alertPlayer.isSetCount = 1;  /* 设置次数限制 */
    
    /* 开始播放第一次 */
    beep_set_frequency(s_alertPlayer.freq);
    beep_set_volume(s_alertPlayer.volume);
    beep_start();
    
    printf("ALERT: 开始自定义播放，频率%dHz，音量%d%%，序列%d段，重复%d次\n", 
           s_alertPlayer.freq, s_alertPlayer.volume, count, s_alertPlayer.count);
}

/**
 * @brief       播放自定义报警提示音（无限循环）
 * @param       freq: 频率
 * @param       volume: 音量(0-100)
 * @param       ...: 时间序列参数（毫秒）
 *              > 0: 响铃持续时间
 *              < 0: 静音持续时间
 *              = 0: 参数结束
 * @retval      无
 * @note        例如：ALERT_PlayCustomInfinite(2000, 80, 200, -100, 200, -100, 200, -400, 0);
 *              表示：2kHz频率，80%音量，无限循环播放
 *              时间序列：响200ms，静100ms，响200ms，静100ms，响200ms，静400ms
 */
void ALERT_PlayCustomInfinite(uint32_t freq, uint8_t volume, ...)
{
    va_list timeList;
    int32_t time;
    uint16_t min_interval = 0xffff;
    uint8_t total_segments = 0;
    
    /* 参数检查 */
    if (freq < 100) freq = 100;
    if (freq > 8000) freq = 8000;
    if (volume > 100) volume = 100;
    
    /* 第一次遍历参数，找出最小时间间隔和总段数 */
    va_start(timeList, volume);
    do
    {
        time = va_arg(timeList, int32_t);
        if (time != 0)
        {
            if (abs(time) < min_interval)
            {
                min_interval = abs(time);
            }
            total_segments++;
        }
    } while (time != 0);
    va_end(timeList);
    
    /* 检查参数有效性 */
    if (total_segments == 0 || min_interval == 0xffff)
    {
        printf("ALERT: 自定义参数无效\n");
        return;
    }
    
    /* 停止当前播放 */
    beep_stop();
    
    /* 设置自定义参数 */
    s_alertPlayer.type = ALERT_TYPE_CUSTOM;
    s_alertPlayer.freq = freq;
    s_alertPlayer.volume = volume;
    s_alertPlayer.count = 0;  /* 0表示无限循环 */
    s_alertPlayer.current_count = 0;
    s_alertPlayer.state = ALERT_STATE_PLAYING;
    s_alertPlayer.is_beeping = 1;
    s_alertPlayer.tic = 0;
    s_alertPlayer.isSetCount = 0;  /* 不设置次数限制，永久运行 */
    
    /* 开始播放第一次 */
    beep_set_frequency(s_alertPlayer.freq);
    beep_set_volume(s_alertPlayer.volume);
    beep_start();
    
    printf("ALERT: 开始无限循环播放，频率%dHz，音量%d%%\n", 
           s_alertPlayer.freq, s_alertPlayer.volume);
}

/* ------------------------------------------------- 报警函数 ----------------------------------------------------- */

/**
 * @brief       简单蜂鸣（无限循环）
 * @param       freq: 频率
 * @param       time: 蜂鸣间隔时间（毫秒）
 * @retval      无
 * @note        例如：ALERT_Beep(2000, 500); 表示2kHz频率，每500ms蜂鸣一次
 */
void ALERT_Beep(uint32_t freq, uint16_t time)
{
    /* 参数检查 */
    if (freq < 100) freq = 100;
    if (freq > 8000) freq = 8000;
    if (time < 10) time = 10;
    
    /* 停止当前播放 */
    beep_stop();
    
    /* 设置简单蜂鸣参数 */
    s_alertPlayer.type = ALERT_TYPE_CUSTOM;
    s_alertPlayer.freq = freq;
    s_alertPlayer.volume = 80;  /* 默认80%音量 */
    s_alertPlayer.duration = time / 2;  /* 蜂鸣时间为间隔的一半 */
    s_alertPlayer.interval = time / 2;  /* 静音时间为间隔的一半 */
    s_alertPlayer.count = 0;  /* 无限循环 */
    s_alertPlayer.current_count = 0;
    s_alertPlayer.state = ALERT_STATE_PLAYING;
    s_alertPlayer.is_beeping = 1;
    s_alertPlayer.tic = 0;
    s_alertPlayer.isSetCount = 0;  /* 不设置次数限制 */
    
    /* 开始播放 */
    beep_set_frequency(s_alertPlayer.freq);
    beep_set_volume(s_alertPlayer.volume);
    beep_start();
    
    printf("ALERT: 开始简单蜂鸣，频率%dHz，间隔%dms\n", freq, time);
}

/**
 * @brief       有限次数蜂鸣
 * @param       freq: 频率
 * @param       time: 蜂鸣间隔时间（毫秒）
 * @param       count: 蜂鸣次数
 * @retval      无
 * @note        例如：ALERT_BeepWithCount(2000, 500, 3); 表示2kHz频率，每500ms蜂鸣一次，重复3次
 */
void ALERT_BeepWithCount(uint32_t freq, uint16_t time, uint8_t count)
{
    /* 参数检查 */
    if (freq < 100) freq = 100;
    if (freq > 8000) freq = 8000;
    if (time < 10) time = 10;
    if (count == 0) count = 1;
    
    /* 停止当前播放 */
    beep_stop();
    
    /* 设置有限次数蜂鸣参数 */
    s_alertPlayer.type = ALERT_TYPE_CUSTOM;
    s_alertPlayer.freq = freq;
    s_alertPlayer.volume = 80;  /* 默认80%音量 */
    s_alertPlayer.duration = time / 2;  /* 蜂鸣时间为间隔的一半 */
    s_alertPlayer.interval = time / 2;  /* 静音时间为间隔的一半 */
    s_alertPlayer.count = count;
    s_alertPlayer.current_count = 0;
    s_alertPlayer.state = ALERT_STATE_PLAYING;
    s_alertPlayer.is_beeping = 1;
    s_alertPlayer.tic = 0;
    s_alertPlayer.isSetCount = 1;  /* 设置次数限制 */
    
    /* 开始播放 */
    beep_set_frequency(s_alertPlayer.freq);
    beep_set_volume(s_alertPlayer.volume);
    beep_start();
    
    printf("ALERT: 开始有限次数蜂鸣，频率%dHz，间隔%dms，次数%d\n", freq, time, count);
}

/**
 * @brief       停止报警提示音播放
 * @param       无
 * @retval      无
 */
void ALERT_Stop(void)
{
    beep_stop();
    s_alertPlayer.state = ALERT_STATE_STOPPED;
    s_alertPlayer.current_count = 0;
    s_alertPlayer.is_beeping = 0;
    s_alertPlayer.tic = 0;
}

/**
 * @brief       暂停报警提示音播放
 * @param       无
 * @retval      无
 */
void ALERT_Pause(void)
{
    if (s_alertPlayer.state == ALERT_STATE_PLAYING)
    {
        beep_stop();
        s_alertPlayer.state = ALERT_STATE_PAUSED;
    }
}

/**
 * @brief       恢复报警提示音播放
 * @param       无
 * @retval      无
 */
void ALERT_Resume(void)
{
    if (s_alertPlayer.state == ALERT_STATE_PAUSED)
    {
        s_alertPlayer.state = ALERT_STATE_PLAYING;
        s_alertPlayer.tic = 0;
    }
}

/* -------------------------------------------- 报警提示音状态查询函数 -------------------------------------------- */

/**
 * @brief       获取报警提示音播放状态
 * @param       无
 * @retval      播放状态
 */
alert_state_e ALERT_GetState(void)
{
    return s_alertPlayer.state;
}

/**
 * @brief       检查是否正在播放报警提示音
 * @param       无
 * @retval      1:正在播放 0:未播放
 */
uint8_t ALERT_IsPlaying(void)
{
    return (s_alertPlayer.state == ALERT_STATE_PLAYING);
}

/**
 * @brief       获取当前报警提示音类型
 * @param       无
 * @retval      提示音类型
 */
alert_type_e ALERT_GetCurrentType(void)
{
    return s_alertPlayer.type;
}

/* -------------------------------------------- 报警提示音模块API函数 -------------------------------------------- */

/**
 * @brief       报警提示音管理器初始化函数
 * @param       无
 * @retval      无
 */
void FML_ALERT_Init(void)
{
    InitAlertPlayer();
    printf("报警提示音管理器初始化完成！\n");
}
